package cate.game.role.res.guild.po.envelope;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDGuild;
import cate.common.table.d.GDObj;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.common.table.guild.GuildEnvelopeRow;
import cate.game.role.res.guild.GuildFuncBase;
import cate.game.role.res.guild.msg.envelope.GuildEnvelopeResp;
import cate.game.role.res.guild.msg.envelope.MyGuildEnvelopeResp;
import cate.game.role.res.guild.po.GuildPO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@NoteClass(value = "公会红包")
public class GuildEnvelopePO extends GuildFuncBase {

    @NoteField(
            value = "公会发红包记录",
            detail = "<红包ID, 当日发放次数>")
    public Map<Integer, Integer> recordMap;

    @NoteField(value = "当前可以抢的红包列表")
    public List<GuildEnvelopeDetailPO> envelopeDetails;

    @NoteField(value = "发红包榜单的成员列表")
    public Map<String, GuildEnvelopeIssuerPO> issuers;

    @JsonIgnore
    @NoteField(value = "公会红包今天已经发放次数")
    public int sendTimes;

    @JsonIgnore
    @Override
    public void initialize(GuildPO guild) {
        super.initialize(guild);
        if (recordMap == null) {
            recordMap = new HashMap<>();
        }

        if (envelopeDetails == null) {
            envelopeDetails = new ArrayList<>();
        }
        if (issuers == null) {
            issuers = new HashMap<>();
        }
    }

    /**
     * 发红包
     */
    public void sendRedEnveLope(Role role, int tid) {
        if(!guildFuncOpenCheck(role)){
            return;
        }
        EcResult r = sendRedEnveLopeCheck(role, tid);
        if (!r.ok()) {
            role.getGame().notice.message(role, r.message);
        }
    }

    public EcResult sendRedEnveLopeCheck(Role role, int tid) {
        EcResult r = new EcResult();
        GuildEnvelopeRow row = role.getGame().table.guild.envelope.get(tid);
        if (row == null) {
            role.getGame().notice.message(role, 310413, "所选红包不存在");
            return r.fail("所选红包不存在");
        }
        Integer num = recordMap.get(row.id);
        if (num != null && num + 1 > row.maxIssueNum) {
            role.getGame().notice.message(role, 310414, "已达到当日发红包次数上限");
            return r.fail("已达到当日发红包次数上限");
        }
        return r.success();
    }

    /**
     * 在成功支付后
     */
    public void afterPay(Role role, int tid) {
        GuildEnvelopeRow row = role.getGame().table.guild.envelope.get(tid);
        // 发红包人的奖励
        if (row == null) {
            role.getGame().notice.message(role, 310415, "红包不存在");
            return;
        }
        MixRes issuerReward = new MixRes(row.issuerRewardStr);
        issuerReward.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.P, row.PNum));
        issuerReward.add(role, true, 0);

        role.getGame().notice.dialogReward(role, issuerReward);
        role.getRes().guild.performance.addPValue(row.PNum);
        role.getGame().notice.message(role, "红包已发出，赶紧去抢红包吧~");

        // 往公会红包列表里面加一个红包
        getFuncDependent().guild.envelope.addEnvelope(role, row);
        // 记录公会成员行为
//        guild.record.addRecord(
//                new GuildLogDetailPO(GDGuild.log.DISTRIBUTE_RED_ENVELOPE, role.getBase().name)
//        );
        // 记录公会活跃
        if (row.taskId == 0) {
            return;
        }

        Map<Integer, Integer> sendMap = role.getRes().guild.envelope.sendMap;
        int sendNum = 1;
        if (sendMap.containsKey(tid)) {
            sendNum = sendMap.get(tid);
            sendNum++;
        }
        sendMap.put(tid, sendNum);

        role.getRes().guild.active.addActive(row.taskId);
        role.sendNow(new MyGuildEnvelopeResp(role));
    }

    /**
     * 抢红包
     */
    public void drawRedEnveLope(Role role, String idHex) {
        if(!guildFuncOpenCheck(role)){
            return;
        }
        if (role.getRes().guild.envelope.drawTime >= GDGuild.redEnvelope.MAX_DRAW_TIME) {
            role.getGame().notice.message(role, 310416, "已达到今日抢红包次数的上限");
            return;
        }
        GuildEnvelopeDetailPO detail = getFuncDependent().guild.envelope.getEnvelope(idHex);
        if (detail == null) {
            role.getGame().notice.message(role, 310417, "红包已经被抢完或者已过期");
            return;
        }
        EcResult r = detail.draw(role);
        if (!r.ok()) {
            return;
        }
        role.getRes().guild.envelope.addTime();

        getFuncDependent().guild.noticeOnline(m -> m.sendNow(new GuildEnvelopeResp(this)));
    }

    /**
     * 获取一个红包的详情
     */
    private GuildEnvelopeDetailPO getEnvelope(String idHex) {
        checkExpire();
        for (GuildEnvelopeDetailPO detail : envelopeDetails) {
            if (StringUtils.equals(detail.uid, idHex)) {
                return detail;
            }
        }
        return null;
    }

    /**
     * 新增一个红包
     */
    public void addEnvelope(Role role, GuildEnvelopeRow row) {
        Integer num = recordMap.get(row.tid);
        if (num == null) {
            num = 0;
        }
        recordMap.put(row.tid, num + 1);
        sendTimes++;

        checkExpire();
        GuildEnvelopeDetailPO detail = new GuildEnvelopeDetailPO(role, row);
        envelopeDetails.add(detail);
        addIssuser(role, row.value);
        // 通知在线成员有新的红包
        getFuncDependent().guild.member.getOnlineRole().forEach(this::noticeUpdate);
    }

    /**
     * 汇率转换 元宝转金币
     */
    private int unifyValue(int amount, byte mtype) {
        if (mtype == GDObj.Num.M1) {
            amount *= GDGuild.TRANSFER_M1_TO_M0;
        }
        return amount;
    }

    /**
     * 更新发红包排行榜
     */
    private void addIssuser(Role role, int value) {
        GuildEnvelopeIssuerPO issuser = issuers.get(role.getUid());
        if (issuser == null) {
            issuser = new GuildEnvelopeIssuerPO(role, value);
            issuers.put(role.getUid(), issuser);
        } else {
            issuser.num++;
            issuser.value += value;
            issuser.updateBase(role);
        }
    }

    /**
     * 红包过期检测
     */
    public void checkExpire() {
        boolean change = false;
        Iterator<GuildEnvelopeDetailPO> it = envelopeDetails.iterator();
        while (it.hasNext()) {
            GuildEnvelopeDetailPO detail = it.next();
            if (detail.isExpire()) {
                it.remove();
                change = true;
            }
        }
        if (change) {
            noticeUpdateAll();
        }
    }

    public void onDaySpan() {
        recordMap.clear();
        sendTimes = 0;
//        this.noticeUpdateAll();
    }

    private void noticeUpdateAll() {
        getFuncDependent().guild.member.getOnlineRole().forEach(this::noticeUpdate);
    }

    /**
     * 通知前端最新的公会红包信息
     */
    public void noticeUpdate(Role role) {
        role.sendNow(new GuildEnvelopeResp(this));
    }

    @Override
    public int getFuncId() {
        return GDFunc.GuildFunc.ENVELOP;
    }

}
